/*
███████╗██╗   ██╗ ██████╗██╗  ██╗
██╔════╝██║   ██║██╔════╝██║ ██╔╝
█████╗  ██║   ██║██║     █████╔╝
██╔══╝  ██║   ██║██║     ██╔═██╗
██║     ╚██████╔╝╚██████╗██║  ██╗
╚═╝      ╚═════╝  ╚═════╝╚═╝  ╚═╝
*/
package Controller;

import Service.imp.UserServiceImp;
import common.utils.JSONUtil;
import common.utils.Result;
import common.utils.TokenManager;
import entity.User;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;

public class AuthFilter implements Filter {

    // 使用Set，查询效率更高
    private final Set<String> whiteList = new HashSet<>(Arrays.asList(
            "/user/login.do",
            "/user/register.do",
            "/user/products.do",
            "/user/product/detail.do"
    ));

    // 【【【不再需要这个，下面有更好的逻辑】】】
    // private final UserServiceImp userserviceimp = new UserServiceImp();

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        /*
        System.out.println("\n\n+-+-+-+-+-+-+-+-+- A U T H - F I L T E R -+-+-+-+-+-+-+-+-+");
        System.out.println("Path: " + req.getServletPath());
        System.out.println("Method: " + req.getMethod());
        System.out.println("-------------------- ALL HEADERS RECEIVED --------------------");

        // 打印所有收到的请求头
        Enumeration<String> headerNames = req.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String headerName = headerNames.nextElement();
            System.out.println("  " + headerName + ": " + req.getHeader(headerName));
        }
        System.out.println("------------------------------------------------------------");
*/

        String path = req.getServletPath();

        /*String _token = req.getHeader("X-Token");
        if (_token == null) {_token=req.getHeader("x-token");}

        // 不管三七二十一，先把拿到的 token 打印出来看看
        System.out.println("Attempting to get 'X-Token' from header...");
        System.out.println(">>>>> Captured Token: [" + _token + "] <<<<<");*/

        // 1. 白名单路径，直接放行，什么都不用管
        if (whiteList.contains(path)||path==null||path.equals("null")||path.isEmpty()) {
            chain.doFilter(req, resp);
            return;
        }

        // --- 从这里开始，都是需要身份验证的路径 ---

        // 2. 从请求头里获取Token
        String token = req.getHeader("X-Token");
        if (token == null) {token=req.getHeader("x-token");}
        if (token == null || token.isEmpty()) {
            System.out.println("老子TOKEN呢???");
            Enumeration<String> headerNames = req.getHeaderNames();
            while (headerNames.hasMoreElements()) {
                String headerName = headerNames.nextElement();
                System.out.println("  " + headerName + ": " + req.getHeader(headerName));
            }
            System.out.println("------------------------------------------------------------");
            JSONUtil.printByJSON(resp, Result.fail("您尚未登录，请先登录",401));
            return; // 【【【关键】】】拒绝后必须立刻返回！
        }

        // 3. 用Token获取用户
        User currentUser = TokenManager.getUserByToken(token);
        if (currentUser == null) {
            System.out.println("老子TOKEN呢???");
            Enumeration<String> headerNames = req.getHeaderNames();
            while (headerNames.hasMoreElements()) {
                String headerName = headerNames.nextElement();
                System.out.println("  " + headerName + ": " + req.getHeader(headerName));
            }
            System.out.println("------------------------------------------------------------");
            JSONUtil.printByJSON(resp, Result.fail("身份认证已过期，请重新登录",401 ));
            return; // 【【【关键】】】拒绝后必须立刻返回！
        }

        // 4. 【【【逻辑修正的核心！！！】】】
        // 如果请求的是管理员路径...
        if (path.startsWith("/admin/")) {
            // ...就检查他是不是管理员
            if (currentUser.getPermission() != 1) {
                // 如果不是，就拒绝访问
                JSONUtil.printByJSON(resp, Result.fail("权限不足，此操作需要管理员身份",403));
                return; // 【【【关键】】】拒绝后必须立刻返回！
            }
        }
        // 如果请求的不是 /admin/ 路径，那它就是普通用户路径，我们不需要额外检查了，
        // 因为只要他能通过 Token 验证，就说明他至少是个合法的普通用户。

        // 5. 验证通过！把用户信息存入request，方便后面的Controller使用
        req.setAttribute("currentUser", currentUser);

        // 6. 完美放行！把请求交给它该去的Controller
        chain.doFilter(req, resp);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void destroy() {}
}